﻿using System;
using System.IO;
using System.Threading;
using System.Windows.Forms;
using Microsoft.Win32;
using WorkLogger.Client.Commands;
using WorkLogger.Client.DataAccess.Repository;
using WorkLogger.Client.Forms;
using WorkLogger.Client.Presenters;
using log4net;
using log4net.Config;

namespace WorkLogger.Client {
	internal static class Program {
		private static MainFormPresenter mainFormPresenter;
		private static readonly ILog Log = LogManager.GetLogger(typeof(Program));
		private static readonly Mutex Mutex = new Mutex(true, "CC8B4039-2048-4792-9180-3ACDA8C2E4EC");

		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		[STAThread]
		private static void Main() {
			if (Mutex.WaitOne(TimeSpan.Zero, true)) {
				XmlConfigurator.Configure();
				Log.Info("Запуск приложения.");
				try {
					RunApplication();
					Log.Info("Остановка приложения.");
				} catch (Exception e) {
					MessageBox.Show("Ошибка в работе приложения. " + e);
					Log.Fatal("Ошибка в работе приложения.", e);
				}
				Mutex.ReleaseMutex();
			}
		}

		private static void RunApplication() {
			string applicationData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
			string workLoggerPath = Path.Combine(applicationData, "WorkLogger");

			Log.InfoFormat("Папка с данными: {0}", workLoggerPath);

			Deployer.Deploy(workLoggerPath);

			RegistryKey registryKey = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
			if (registryKey != null)
				registryKey.SetValue("WorkLogger", Application.ExecutablePath);

			Application.EnableVisualStyles();
			Application.SetCompatibleTextRenderingDefault(false);
			var mainForm = new MainForm();
			var workDayRepository = new WorkDayRepository();
			var systemClock = new SystemClock();
			var workDayManager = new WorkDayManager(systemClock, workDayRepository);
			AppOptions appOptions = AppOptions.Load();
			var workTimeCalculator = new WorkTimeCalculator();
			var commandFactory = new CommandFactory(workDayManager, appOptions, workTimeCalculator, systemClock);
			var lunchTimePresenter = new LunchTimePresenter(mainForm.LunchTimeView, workDayManager);
			var mainMenuPresenter = new MainMenuPresenter(mainForm.MainMenu, appOptions, workDayRepository, systemClock,
			                                              workTimeCalculator);
			mainFormPresenter = new MainFormPresenter(mainForm, workDayManager, workTimeCalculator, appOptions,
			                                          commandFactory, lunchTimePresenter, mainMenuPresenter);
			SystemEvents.SessionSwitch += SystemEventsSessionSwitch;
			Application.Run(mainForm);
		}

		private static void SystemEventsSessionSwitch(object sender, SessionSwitchEventArgs e) {
			switch (e.Reason) {
				case SessionSwitchReason.SessionLock:
					Log.Info("Компьютер заблокирован.");
					mainFormPresenter.SessionLock(DateTime.Now);
					break;
				case SessionSwitchReason.SessionUnlock:
					Log.Info("Компьютер разблокирован.");
					mainFormPresenter.SessionUnlock(DateTime.Now);
					break;
			}
		}
	}
}